#!/usr/bin/env node

/**
 * CodeMind MCP Server
 * @version 0.4.1
 * @description A stable MCP server for GitCode and Mindmap generation, refactored to use McpServer.
 */

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import { gitcodeRequest } from "./gitcode.js";
import { cloneRepoAndMindmap } from "./mindmap.js";

const SERVER_VERSION = '0.4.1';

// Define Zod schemas for tool inputs for robust validation
const GitcodeArgsSchema = z.object({
  baseUrl: z.string().optional(),
  token: z.string(),
  method: z.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]),
  path: z.string(),
  query: z.record(z.any()).optional(),
  body: z.record(z.any()).optional(),
  headers: z.record(z.string()).optional(),
});

const MindmapArgsSchema = z.object({
  repoUrl: z.string(),
  targetDir: z.string().optional(),
});

class CodeMindMCPServer {
  private server: McpServer;

  constructor() {
    console.log(`[CodeMind] Initializing server v${SERVER_VERSION}...`);
    this.server = new McpServer({
      name: '@lucianaib/codemind-mcp',
      version: SERVER_VERSION,
      // CRITICAL: This capability flag is required by the SDK version to enable tools.
      capabilities: {
        tools: true,
      },
    });
    this.registerTools();
  }

  private registerTools(): void {
    // Tool 1: gitcode_request
    this.server.registerTool(
      "gitcode_request",
      {
        description: "A general-purpose tool for calling the GitCode API.",
        inputSchema: GitcodeArgsSchema.shape,
      },
      async (args: z.infer<typeof GitcodeArgsSchema>) => {
        try {
          console.log(`[CodeMind] Calling tool 'gitcode_request' for path: ${args.path}`);
          const result = await gitcodeRequest(args);
          return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
        } catch (error) {
          console.error(`[CodeMind] Error executing 'gitcode_request':`, error);
          return {
            isError: true,
            content: [{ type: "text", text: `GitCode request failed: ${error instanceof Error ? error.message : String(error)}` }],
          };
        }
      }
    );

    // Tool 2: repo_clone_and_mindmap
    this.server.registerTool(
      "repo_clone_and_mindmap",
      {
        description: "Clones a repository, summarizes documents, and generates a mind map.",
        inputSchema: MindmapArgsSchema.shape,
      },
      async (args: z.infer<typeof MindmapArgsSchema>) => {
        try {
          console.log(`[CodeMind] Calling tool 'repo_clone_and_mindmap' for repo: ${args.repoUrl}`);
          const result = await cloneRepoAndMindmap({
            repoUrl: args.repoUrl,
            targetDir: args.targetDir,
            summaryFile: "PROJECT_SUMMARY.md",
            prompt: "Please generate a mind map based on the following project documentation.",
          });
          const text = `Repository directory: ${result.repoDir}\nSummary file: ${result.summaryFile}\nMind map URL: ${result.mindmapUrl}\n\n${result.message}`;
          return { content: [{ type: "text", text }] };
        } catch (error) {
          console.error(`[CodeMind] Error executing 'repo_clone_and_mindmap':`, error);
          return {
            isError: true,
            content: [{ type: "text", text: `Mind map generation failed: ${error instanceof Error ? error.message : String(error)}` }],
          };
        }
      }
    );
  }

  public async run(): Promise<void> {
    const transport = new StdioServerTransport();
    process.on('SIGINT', () => {
      console.log('[CodeMind] SIGINT received, shutting down.');
      this.server.close();
      process.exit(0);
    });
    await this.server.connect(transport);
    console.error(`CodeMind MCP Server v${SERVER_VERSION} is running successfully.`);
  }
}

// Main execution block
try {
  const server = new CodeMindMCPServer();
  server.run();
} catch (error) {
  console.error('Failed to initialize or run the server:', error);
  process.exit(1);
}